Работа с циклами почти во всех языках программирования имеет свои нюансы, особенно если в теле цикла выполняется изменение данных по определенным критериям.
В одних языках программирования циклы имеют сложный синтаксис, а в других — наоборот, простой. Python сочетает оба варианта: с одной стороны, он предлагает стандартные ключевые слова for, while и break, а с другой — специальные функции для итерации последовательностей и изменения их данных. Одна из таких функций — map().
В этой статье мы подробно разберем, что делает функция map() в Питоне и для каких задач она подходит больше всего.
Все демонстрируемые скрипты запускались с помощью интерпретатора Python версии 3.10.12, установленном на облачном сервере Timeweb Cloud под управлением операционной системы Ubuntu 22.04.
Каждый скрипт размещался в отдельном файле с расширением .py (например, some_script.py), после чего запускался с помощью команды интерпретатора Python:
Серверы 152-ФЗ
полностью отвечает закону о защите
персональных данных.
Что такое map() в Python
Функция map() в Python — это встроенная функция, которая применяет указанный метод ко всем элементам одного или нескольких итерируемых объектов, после чего возвращает итератор с результатами этих применений.
В самом простом случае код с map() выглядит примерно так:
Без map() эквивалентная логика записывалась бы следующим образом:
Или даже так:
Во всех случаях консольный вывод будет одинаковым:
Код с использованием метода map() в Python имеет ряд преимуществ по сравнению с кодом, в котором используются более традиционные способы изменения значений итерируемых объектов:
- Лаконичность. В одну строку описывает, что сделать с элементами, а не как проходить по элементам.
- Ленивая обработка. Возвращает итератор, а не сразу весь список, экономя память при больших объемах данных.
- Параллельность. Обрабатывает значения как одного, так и двух и более итерируемых объектов, автоматически останавливаясь на конце самого короткого из них. Можно сказать, что это основное, для чего используется функция
map(). - Отсутствие служебного кода. Для выполнения итерации с пересчетом значений не требуется ручное создание дополнительных объектов.
- Функциональный стиль. Легко вкладывается в цепочки с функциями
filter(),reduce(),sorted(),any(),all()без промежуточных объектов.
Таким образом, map() — быстрый, оптимизированный (за счет ленивой обработки) и декларативный способ применения простой функции ко всем элементам одной или нескольких последовательностей.
Базовое использование map()
Функция map() имеет следующую схему:
Возвращаемым значением является итерируемый объект <map object>.
То есть map() применяет функцию с фиксированным числом аргументов, которое соответствует количеству итерируемых объектов.
Создание итератора
В самом простом случае, выполнив функцию map(), можно получить итерируемый объект, который впоследствии может быть использован самыми разными способами:
Итерация функцией
Полученный итератор можно перебирать с помощью функции next():
Итерация циклом
Можно перебрать сразу все значения с помощью цикла for:
Или с помощью цикла while:
Создание списка из итератора
Итератор — не самый удобный объект для работы с последовательностями. Его области применения весьма специфичны. Поэтому итерируемый объект можно сконвертировать в список — так проще работать с элементами:
Если в map() передать количество списков, не соответствующее количеству аргументов обрабатываемой функции, то появится ошибка:
Таким образом, количество переданных списков должно равняться количеству аргументов обрабатываемой функции:
При этом никто не запрещает использовать большее количество списков:
Консольный вывод этого примера будет иметь следующий вид:
Использование map() с лямбда-функциями
Преобразование элементов в map() можно выполнять с помощью лямбда-функций — небольших анонимных функций, определяемых «на лету» без ключевого слова def:
Как и обычная функция, лямбда-функция может иметь несколько аргументов:
Как правило, лямбда-выражения используются в тех местах, где нужна простая логика без повторного использования. Например, в map(), filter(), sorted(), min() и множестве других функций, предназначенных для преобразования данных.
Создание итерируемых объектов из map()
На самом деле функцию map() можно использовать для создания любых итерируемых объектов, которые поддерживает язык Python:
Это лишь основные объекты, которые могут быть созданы с помощью map(). Более того, любая функция или класс, принимающие на вход объект Iterable или Iterator, может сразу работать с объектом map без предварительного преобразования.
Использование map() со встроенными функциями Python
Метод map() может использоваться со множеством встроенных функций языка Python — для наглядности их удобнее представить в виде отдельных категорий:
- Преобразование типов:
bytearray,bytes,chr,ord,str,repr,int,float,complex,bool,dict,list,tuple,set,frozenset,memoryview. - Числовые функции:
abs,divmod,pow,round,max,min,sum,hex,oct,bin,complex. - Последовательности и итераторы:
len,iter,next,enumerate,filter,map,zip,sorted,reversed,slice,range. - Объекты и атрибуты:
classmethod,staticmethod,property,getattr,setattr,hasattr,delattr,isinstance,issubclass,type,super,object. - Инспекция и помощь:
dir,globals,locals,vars,help,id,callable,hash. - Логические функции:
all,any. - Ввод-вывод и исполнение кода:
print,input,open,eval,exec,compile,import. - Форматирование и представление:
format,ascii.
Встроенных функций, способных работать в связке с map(), так много, что в этом руководстве будут рассмотрены лишь самые основные.
Преобразование типов
В самом простом случае функцию map() можно использовать для преобразования элементов итерируемых объектов в другие типы:
Числовые функции
Функции, выполняющие преобразования отдельных чисел, могут быть использованы в связке с map():
Последовательности и итераторы
С помощью map() можно выполнять операции над последовательностью последовательностей:
Объекты и атрибуты
Многие функции, работающие с экземплярами классов, могут быть использованы в map():
Инспекция и помощь
Вспомогательные функции, предоставляющие дополнительную информацию об объектах Python, тоже могут быть использованы вместе с map():
Логические функции
Функция map() позволяет формировать логические цепочки:
Ввод-вывод и исполнение кода
С помощью функции map() можно выполнить множественный вывод в консоль или исполнить сразу несколько выражений:
Форматирование и представление
С помощью map() можно применить функции преобразования значений сразу ко всем элементам итерируемого объекта:
Использование map() внутри класса
В функцию map() можно передавать методы класса с помощью ключевого слова self:
Пример реального использования map()
Для полного понимания, какие задачи может решать функция map(), ее использование лучше всего рассмотреть на примере, приближенном к реальности.
Предположим, есть набор физически существующих датчиков температуры, которые собирают информацию об окружающей среде и передают ее на удаленный сервер для обработки сырых данных. Этот сервер подготавливает наглядные отчёты в понятном человеку виде — чем больше метрик, тем лучше.
Одна из важных функций подобного обработчика — автоматическая конвертация температуры из разных систем счисления. Например, из градусов Цельсия в градусы Фаренгейта и наоборот.
В этом случае функция map() может быть использована для последовательного однообразного преобразования данных, собранных большим количеством датчиков:
Отличие map() от list comprehension
List comprehension в Python — это компактный способ создать новый список, применив выражение к каждому элементу итерируемого объекта.
Конструкция имеет следующую схему:
В данном случае:
- ВЫРАЖЕНИЕ. Любое корректное выражение Python, результат которого станет элементом нового списка.
- ЭЛЕМЕНТ. Имя переменной, которой по очереди присваиваются значения из исходного итерируемого объекта.
- ОБЪЕКТ. Объект, по которому можно итерироваться (список, кортеж, строка, range, генератор и т. п.)
Например, можно возвести каждый элемент уже существующего списка в степень, получив совершенно новый список:
Функция map() и конструкция list comprehension решают похожие задачи — применяют функцию к элементам существующего итерируемого объекта, получая новый итерируемый объект.
Однако между ними есть ряд существенных различий:
- Тип возвращаемого результата. Функция
map()в Питоне возвращает ленивый итератор который выдает (выполняет функцию) значения по мере обхода, а list comprehension сразу создает список со всеми результатами. - Ленивость. Функция
map()не вычисляет значения всех элементов сразу, а выполняет расчет по мере надобности. Напротив, list comprehension сразу вычисляет конечный результат, целиком сохраняя все новые значения. - Производительность. Функция
map()работает быстрее list comprehension — она реализована на C без генерации байт-кода Python в каждом шаге. - Синтаксис. Функция
map()подчеркивает функциональный стиль, а list comprehension ближе к классическому стилю Python, который зачастую читается естественнее. - Обработка нескольких объектов. Функция
map()поддерживает параллельную обработку сразу несколько итерируемых объектов, а list comprehension потребует для этого использование дополнительной функцииzip(). - Выражение vs Функция. Выполнение
map()требует готовой функции или лямбда, а list comprehension — только выражение Python.
Функцию map() лучше всего использовать, когда заранее есть функция (встроенная или пользовательская), которую необходимо применить ко всем элементам по мере надобности.
Конструкция list comprehension предпочтительна, когда необходимо сразу получить список новых элементов с использованием условий, вложенных циклов или другой сложной логики.
Подготовили для вас выгодные тарифы на облачные серверы
477 ₽/мес
657 ₽/мес
Заключение
Функция map() — универсальный инструмент для параллельного изменения значений элементов одного или нескольких итерируемых объектов.
Работает быстро, оптимизирована для большого объема данных и имеет функциональный, декларативный стиль, позволяющий описывать цепочки преобразований в связке со множеством других похожих функций.
Короче говоря, это «однолинейный конвейер» для превращения данных: на вход подаются функция и последовательности, а на выходе получается «ленивый» результат. Просто и быстро!
